package com.newbe.security.config;

import com.newbe.security.service.MyUserDetailsService;
import com.newbe.security.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

/**
 * @Auther: Newbe
 * @Date: 2020/3/29 15:22
 * @Description:自定义认证实现类
 */
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        //1.获取表单的用户和密码
        //1.1表单用户名
        String username = authentication.getName();
        //1.2表单密码
        String password = authentication.getCredentials().toString();
        System.out.println("表单的用户名和密码"+username+":"+password);

        //2.获取数据库userDetails
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        //2.1获取数据库存储的用户名
        String rowUsername = userDetails.getUsername();
        //2.2获取数据库存储的密码
        String rowPassword = userDetails.getPassword();
        System.out.println("数据库用户和数据库密码："+rowUsername+":"+rowPassword);

        //3.判断两者是否一致，一致则通过认证
        //3.1判断密码是否一致
        String pd = MD5Util.encode(password);
        if(pd.equals(rowPassword)){
            //3.2将用户凭证信息封装，给Authentication认证
            return new UsernamePasswordAuthenticationToken(userDetails,password,userDetails.getAuthorities());
        }
        //3.3不一致返回错误信息
        else {
            throw new BadCredentialsException("用户名或密码错误");
        }
    }
    //接受一个authentication参数，用来判断传进来的authentication是不是该AuthenticationProvider能够处理的类型
    @Override
    public boolean supports(Class<?> aClass) {
        return aClass.equals(UsernamePasswordAuthenticationToken.class);
    }
}
